package com.smalluz.ad.modules.oe.api.impl;
 

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

import org.apache.commons.lang3.StringUtils;

import com.smalluz.ad.modules.common.config.MediaConfigStorage;
import com.smalluz.ad.modules.common.enums.GrantType;
import com.smalluz.ad.modules.common.enums.MediaApiUrl;
import com.smalluz.ad.modules.common.exception.ApiException;
import com.smalluz.ad.modules.common.tools.OkHttpUtils;
import com.smalluz.ad.modules.common.util.json.JacksonUtils;
import com.smalluz.ad.modules.oe.api.OeOpenService;
import com.smalluz.ad.modules.oe.api.OpenComponentService;
import com.smalluz.ad.modules.oe.bean.OAuth2TokenRequest;
import com.smalluz.ad.modules.oe.bean.RefreshTokenRequest;
import com.smalluz.ad.modules.oe.result.AccessTokenResult;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class OeOpenServiceImpl implements OeOpenService {
    @Getter
    private OkHttpUtils okHttpUtils = new OkHttpUtils();
    
    @Getter
    private OpenComponentService openComponentService = new OpenComponentServiceImpl(this);
    
    private MediaConfigStorage mediaConfigStorage;

    @Override
    public String getAccessToken(Boolean forceRefresh) {
        final MediaConfigStorage config = this.getMediaConfigStorage();
        if (config.isAccessTokenValid() && !forceRefresh) {
            return config.getAccessToken();
        }

        Lock lock = config.getAccessTokenLock();
        boolean locked = false;
        try {
            do {
                locked = lock.tryLock(100, TimeUnit.MILLISECONDS);
                if (!forceRefresh && config.isAccessTokenValid()) {
                    return config.getAccessToken();
                }
            } while (!locked);
            AccessTokenResult acRes = this.getAccessTokenEntity();
            return acRes.getData().getAccessToken();

        }  catch (InterruptedException e) {
            throw new ApiException(e);
        } finally {
            if (locked) {
                lock.unlock();
            }
        }


    }

    @Override
    public AccessTokenResult getAccessTokenEntity() {
        final MediaConfigStorage config = this.getMediaConfigStorage();

        log.info("~~~~设置的配置参数： {}",config.getAppId());
        log.info("~~~~设置的配置参数： {}",config.getSecret());
        log.info("~~~~设置的配置参数： {}",config.getAuthCode());
        String responseContent = "";
        if(StringUtils.isNotBlank(config.getRefreshAccessToken()) && config.isRefreshAccessTokenValid()) {
            
            log.info("~~~~走刷新参数： {}",config.getRefreshAccessToken());
            responseContent =  this.refreshAccessToken();
        }else {
            responseContent =  this.post(MediaApiUrl.OAuth2.OAUTH2_OPEN_API_OAUTH2_ACCESS_TOKEN, OAuth2TokenRequest.builder()
                .appid(config.getAppId())
                .secret(config.getSecret())
                .grantType(GrantType.OceanEngineGrantType.AUTH_CODE.getCode())
                .authCode(config.getAuthCode())
                .build());
        }

        log.info("~~~~调用接口返回： {}",responseContent);
        AccessTokenResult acRes = AccessTokenResult.fromJson(Objects.requireNonNull(responseContent)) ;
        //更新token存储机制
        //config.updateAccessToken(acRes);
        return acRes;
    }


    @Override
    public String post(MediaApiUrl url, Object object) throws ApiException {
        return this.okHttpUtils.post(url.getUrl(), JacksonUtils.bean2Jsn(object));
    }


    @Override
    public String get(MediaApiUrl url, Object object) throws ApiException {
        return this.okHttpUtils.get(this.getAccessToken(), url.getUrl(), JacksonUtils.bean2Jsn(object));
    }

    @Override
    public String refreshAccessToken() {
        final MediaConfigStorage config = this.getMediaConfigStorage();
        return this.post(MediaApiUrl.OAuth2.OAUTH2_OPEN_API_REFRESH_ACCESS_TOKEN, RefreshTokenRequest.builder()
            .appid(config.getAppId())
            .secret(config.getSecret())
            .refreshToken(config.getRefreshAccessToken())
            .grantType(GrantType.OceanEngineGrantType.REFRESH_TOKEN.getCode())
            .build());
    }

    @Override
    public String getAccessToken() {
        return this.getAccessToken(false);
    }

    @Override
    public MediaConfigStorage getMediaConfigStorage() {
        return this.mediaConfigStorage;
    }

    @Override
    public void setConfigStorage(MediaConfigStorage configProvider) {
        this.mediaConfigStorage = configProvider;
    }

    @Override
    public void setMultiConfigStorages(Map<String, MediaConfigStorage> configStorages) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void addConfigStorage(String mpId, MediaConfigStorage configStorages) {
        this.mediaConfigStorage = configStorages;
    }

    @Override
    public void setMultiConfigStorages(Map<String, MediaConfigStorage> configStorages, String defaultMpId) {
        // TODO Auto-generated method stub
        
    }
 
}
